#ifndef _CONTROL_H_
#define _CONTROL_H_

#include "carpark.h"
#include "findline.h"
#include "myconfig.h"
#include "roadblock.h"
#include "rotate.h"
#include "seekNodeWay.h"
#include "speedUp.h"
#include "stdint.h"

#define NODE_FORK_NUM \
  15  // 地图中下一节点岔道最多的数目 * 下下节点岔道最多的数目
#define NODE_NUM 50  // 地图中节点的数目
/*对路段信息进行记录*/
typedef struct {
  uint8_t nextNode;            // 下一个节点
  uint8_t nextNextNode;        // 下下一个节点
  FindLine findLineWay;        // 寻线方法
  RoadBlockType roadBlockWay;  // 障碍类型
  SpeedUpType speedUpWay;      // 加速类型
  uint16_t speedUpParam_After;  // 加速参数:时间或者距离,障碍后的加速参数
  SeekNodeWayType seekNodeWay;  // 找点方法
  CarParkType carParkWay;       // 停车方法
  RotateType rotateWay;         // 旋转类型
  uint16_t speedUpParam_Before;  // 加速参数:时间或者距离，障碍前的加速参数
} linkInfoTypeDef;
// 路段运行状态记录器
typedef struct {
  My_StatusTypeDef F_LineState;       // 寻线状态
  My_StatusTypeDef F_RoadBlockState;  // 过障碍状态
  My_StatusTypeDef speedUpState;      // 加速状态
  My_StatusTypeDef seekNodeState;     // 找点状态
  My_StatusTypeDef carParkState;      // 停车状态
  My_StatusTypeDef RotateState;       // 转弯状态
} runStateTypeDef;
typedef struct ControlCenter {
  const linkInfoTypeDef *sectionInfo;  // 路段信息
  runStateTypeDef *runState;           // 路段运行状态记录器
  uint8_t nodeNum;                     // 现在所在的节点数，从1开始，走完一个节点加1
  uint8_t findLineFlag;  // 巡线方法初始化标志位 0:未初始化 1:已初始化
  // 寻线方法，在路障处理时要做更改,所以要独立出来，其他的方法均可在路段信息中找到
  FindLine findLineWay;
  // 更新状态:运行态指更新完成，就绪态指当前路段已经走完，需要更新，退出态指全部路段已经走完，不需要更新
  My_StatusTypeDef update;

  const uint8_t *runMethodTable;  // 路线图  2024/1/12新增
  bool (*refresh) (void);  // 刷新函数 2024/6/15新增,用于周期性刷新各种方法，如巡线，加速等
} ControlCenterTypeDef;

extern ControlCenterTypeDef gl_controlCenter;  // 全局控制中心
extern const uint8_t runMethodTable[][100];  // 路线图，主函数中定义了
extern const uint8_t runMethodTable2[][100];  // 第二次奔跑的路线图，主函数中定义了
extern const uint8_t runMethodDoor[][100];  // 红绿灯切换的路线图，主函数中定义了
extern const linkInfoTypeDef mapInfo[][NODE_FORK_NUM];  // 地图信息

int getNextNode(ControlCenterTypeDef *controlCenter);

int getNowNode(ControlCenterTypeDef *controlCenter);

void controlCenterInit(ControlCenterTypeDef *controlCenter,
                       const linkInfoTypeDef mapInfo[][NODE_FORK_NUM],
                       const uint8_t *runMethodTable);
void controlCenterUpdate(ControlCenterTypeDef *controlCenter,
                         const linkInfoTypeDef mapInfo[][NODE_FORK_NUM]);
void changeRunMethodTable(ControlCenterTypeDef *controlCenter,
                          const linkInfoTypeDef mapInfo[][NODE_FORK_NUM],
                          const uint8_t *runMethodTable);
bool refresh_Time();
void setRefreshFunction(ControlCenterTypeDef *controlCenter,
                        bool (*refresh)(void));
#endif
